﻿//----------------------------------------------------------------
// <copyright file="TeamFoundationFacadeTest.cs" company="Microsoft">
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// </copyright>
//----------------------------------------------------------------

using System.Configuration;
using System.Xml;
using System.Xml.Linq;
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.WorkItemTracking.Client;
using MptCodeLibrary.Configuration;
using MptCodeLibrary.TeamFoundation;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Collections.Generic;

namespace Test.UnitTest
{
    
    
    /// <summary>
    ///This is a test class for TeamFoundationFacadeTest and is intended
    ///to contain all TeamFoundationFacadeTest Unit Tests
    ///</summary>
    [TestClass]
    public class TeamFoundationFacadeTest : UnitTestBase
    {
        private static TeamFoundationFacade teamFoundationFacade;
        private static string tfsServerUrl;
        private static string teamProjectName;
        private const string customWorkItemTypeName = "CustomWITNotInProject";

        //Use ClassInitialize to run code before running the first test in the class
        [ClassInitialize()]
        public static void MyClassInitialize(TestContext testContext)
        {
            tfsServerUrl = ConfigurationManager.AppSettings["testTfsServer"];
            teamProjectName = ConfigurationManager.AppSettings["testProjectName"];

            teamFoundationFacade = new TeamFoundationFacade();

            Assert.IsTrue(teamFoundationFacade.ProjectExists(tfsServerUrl, teamProjectName),
                          "The test project doesn't exist on the server or you don't have access.  Verify the values in the test's config file and try again");
        }

        //Use ClassCleanup to run code after all tests in a class have run
        //[ClassCleanup()]
        //public static void MyClassCleanup()
        //{
        //}
        
        //Use TestInitialize to run code before running each test
        //[TestInitialize()]
        //public void MyTestInitialize()
        //{
        //}
        
        //Use TestCleanup to run code after each test has run
        //[TestCleanup()]
        //public void MyTestCleanup()
        //{
        //}
        
        [TestMethod]
        public void GetWorkItemsForProjectOfTypeReturnsHistory()
        {
            IEnumerable<WorkItemSummary> actual = teamFoundationFacade.GetWorkItemsForProjectOfType(tfsServerUrl,
                                                                                                    teamProjectName,
                                                                                                    "Bug");
            foreach (WorkItemSummary workItemSummary in actual)
            {
                Assert.IsTrue(workItemSummary.Title.Length > 0);
            }
        }

        [TestMethod]
        public void ChangedWorkItemsTestWithNoProjectsSupplied()
        {
            IEnumerable<WorkItemSummary> actual = teamFoundationFacade.ChangedWorkItems(tfsServerUrl, new List<string>());
            foreach (WorkItemSummary workItemSummary in actual)
            {
                Assert.IsTrue(workItemSummary.Title.Length > 0);
            }
        }

        [TestMethod]
        public void GetEventWorkItemTypesForProjects()
        {
            List<string> projectNames = new List<string> {teamProjectName};
            List<string> tfsServers = new List<string> {tfsServerUrl};

            IEnumerable<string> witNames = teamFoundationFacade.GetEventWorkItemTypesForProjects(tfsServers, projectNames);
            foreach (string witName in witNames)
            {
                Assert.IsTrue(witName.Length > 0);
            }
        }

        [TestMethod]
        public void GetEventWorkItemTypesForProjectsAndNoProjectNames()
        {
            List<string> projectNames = new List<string>();
            List<string> tfsServers = new List<string> { tfsServerUrl };

            IEnumerable<string> witNames = teamFoundationFacade.GetEventWorkItemTypesForProjects(tfsServers, projectNames);
            foreach (string witName in witNames)
            {
                Assert.IsTrue(witName.Length > 0);
            }
        }

        [TestMethod]
        public void ChangedWorkItemsTestWithProjectsSupplied()
        {
            List<string> projects = new List<string> { teamProjectName, teamProjectName };
            IEnumerable<WorkItemSummary> actual = teamFoundationFacade.ChangedWorkItems(tfsServerUrl, projects);
            foreach (WorkItemSummary workItemSummary in actual)
            {
                Assert.IsTrue(workItemSummary.Title.Length > 0);
            }
        }

        [TestMethod]
        public void VerifyGetUpdateWorkItemTypeForProjectTest()
        {
            teamFoundationFacade.UpdateWorkItemTypeForProject(tfsServerUrl, teamProjectName, customTestWit);

            XDocument customWit = XDocument.Parse(customTestWit);

            string actual = teamFoundationFacade.GetWorkItemTypeForProject(tfsServerUrl, teamProjectName, customWorkItemTypeName);
            Assert.AreEqual(customWit.ToString(), XDocument.Parse(actual).ToString());
        }
        
        private const string customTestWit = @"
<witd:WITD application=""Work item type editor"" version=""1.0""  xmlns:witd=""http://schemas.microsoft.com/VisualStudio/2005/workitemtracking/typedef"">
    <WORKITEMTYPE name=""CustomWITNotInProject"">
        <DESCRIPTION>Includes information to track a CustomWITNotInProject</DESCRIPTION>
        <FIELDS>
            <FIELD name=""Title"" refname=""System.Title"" type=""String""  reportable=""dimension"">
                <HELPTEXT>Short description of the task used to differentiate it in a list or report</HELPTEXT>
                <REQUIRED/>
            </FIELD>
            <FIELD name=""State"" refname=""System.State"" type=""String"" reportable=""dimension"" />
            <FIELD name=""Rev"" refname=""System.Rev"" type=""Integer"" reportable=""dimension"" />
            <FIELD name=""Changed By"" refname=""System.ChangedBy"" type=""String"" reportable=""dimension"" />
            <FIELD name=""Reason"" refname=""System.Reason"" type=""String"" reportable=""dimension"" />
            <FIELD name=""Iteration Path"" refname=""System.IterationPath"" type=""TreePath"" reportable=""dimension"" />
            <FIELD name=""IterationID"" refname=""System.IterationId"" type=""Integer"" />
            <FIELD name=""Assigned To"" refname=""System.AssignedTo"" type=""String"" reportable=""dimension"">
                <HELPTEXT>The person assigned to do the work</HELPTEXT>
                <ALLOWEDVALUES expanditems=""true"" filteritems=""excludegroups"">
                    <LISTITEM value=""[project]\Coordinators"" />
                    <LISTITEM value=""[project]\Developers"" />
                </ALLOWEDVALUES>
            </FIELD>
            <FIELD name=""Work Item Type"" refname=""System.WorkItemType"" type=""String"" reportable=""dimension"" />
            <FIELD name=""Created Date"" refname=""System.CreatedDate"" type=""DateTime"" reportable=""dimension"" />
            <FIELD name=""Created By"" refname=""System.CreatedBy"" type=""String"" reportable=""dimension"" />
            <FIELD name=""Description"" refname=""System.Description"" type=""PlainText"" />
            <FIELD name=""History"" refname=""System.History"" type=""History"" />
            <FIELD name=""ExternalLinkCount"" refname=""System.ExternalLinkCount"" type=""Integer"" />
            <FIELD name=""RelatedLinkCount"" refname=""System.RelatedLinkCount"" type=""Integer"" />
            <FIELD name=""Team Project"" refname=""System.TeamProject"" type=""String"" reportable=""dimension"" />
            <FIELD name=""HyperLinkCount"" refname=""System.HyperLinkCount"" type=""Integer"" />
            <FIELD name=""AttachedFileCount"" refname=""System.AttachedFileCount"" type=""Integer"" />
            <FIELD name=""Node Name"" refname=""System.NodeName"" type=""String"" />
            <FIELD name=""Area Path"" refname=""System.AreaPath"" type=""TreePath"" reportable=""dimension"" />
            <FIELD name=""Revised Date"" refname=""System.RevisedDate"" type=""DateTime"" />
            <FIELD name=""Changed Date"" refname=""System.ChangedDate"" type=""DateTime"" reportable=""dimension"" />
            <FIELD name=""ID"" refname=""System.Id"" type=""Integer"" reportable=""dimension"" />
            <FIELD name=""AreaID"" refname=""System.AreaId"" type=""Integer"" />
            <FIELD name=""Authorized As"" refname=""System.AuthorizedAs"" type=""String"" />
        </FIELDS>
        <WORKFLOW>
            <STATES>
                <STATE value=""Proposed"" />
            </STATES>
            <TRANSITIONS>
                <TRANSITION from="""" to=""Proposed"">
                    <REASONS>
                        <DEFAULTREASON value=""New"" /> 
                    </REASONS>
                </TRANSITION>
            </TRANSITIONS>
        </WORKFLOW>
        <FORM><Layout></Layout></FORM>
    </WORKITEMTYPE>
</witd:WITD>
";
    }
}
